#include "rga_wrapper.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include "rga_v2/src/im2d_api/im2d.hpp"
#include "rga_v2/src/RockchipRga.h"
#include "rga_v2/src/RgaUtils.h"
#include "rga_v2/src/rga.h"

RgaWrapper::RgaWrapper(){
}

RgaWrapper::~RgaWrapper(){
    printf("rga test exit\n");
}

int RgaWrapper::init(RgaCfg cmd){
    mCfg = cmd;
    if(checkCmd(cmd) < 0){
        printf("checkCmd faile!\n");
        return -1;
    }

    memset(&mSrcRect, 0, sizeof(mSrcRect));
	memset(&mDstRect, 0, sizeof(mDstRect));
	memset(&mSrcRgaBuf, 0, sizeof(mSrcRgaBuf));
	memset(&mDstRgaBuf, 0, sizeof(mDstRgaBuf));
    return 0;
}

int RgaWrapper::checkCmd(RgaCfg cmd){
    printf("mSrcRgaBuf w:%d h:%d fmt:%d mDstRgaBuf w:%d h:%d fmt:%d\n",
        cmd.src_w, cmd.src_h, cmd.src_fmt,
        cmd.dst_w, cmd.dst_h, cmd.dst_fmt);
        
    if(mCfg.src_w < 2 || mCfg.src_h < 2 || mCfg.dst_h > 4096 || mCfg.dst_w > 4096 ||\
        (mCfg.src_fmt >= RK_FORMAT_UNKNOWN || mCfg.src_fmt < RK_FORMAT_RGBA_8888)){
        printf("input params invaild!\n");
        return -1;
    }

    return 0;
}

int RgaWrapper::resizeImage(uint8_t *inputBuf, uint8_t* outputBuf){

    mSrcRgaBuf = wrapbuffer_virtualaddr(inputBuf, mCfg.src_w, mCfg.src_h, mCfg.src_fmt);
    mDstRgaBuf = wrapbuffer_virtualaddr(outputBuf, mCfg.dst_w, mCfg.dst_h, mCfg.dst_fmt);
    if(mSrcRgaBuf.width == 0 || mDstRgaBuf.width == 0) {
        printf("%s, %s\n", __FUNCTION__, imStrError());
        return -1;
    }

    mSrcRgaBuf.format = mCfg.src_fmt;
    mDstRgaBuf.format = mCfg.dst_fmt;
    
    int ret = imcheck(mSrcRgaBuf, mDstRgaBuf, mSrcRect, mDstRect);
    if (IM_STATUS_NOERROR != ret) {
        printf("%d, check error! %s \n", __LINE__, imStrError((IM_STATUS)ret));
        return -1;
    }
    
    // struct timeval start, end;
    // gettimeofday(&start, NULL);
    IM_STATUS STATUS = imresize(mSrcRgaBuf, mDstRgaBuf);
    //  gettimeofday(&end, NULL);
    // long usec1 = 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);
    // printf("resize .... cost time %ld us, %s\n", usec1, imStrError(STATUS));
    return 0;
}


int RgaWrapper::cvtColorImage(uint8_t *inputBuf, uint8_t* outputBuf){

    mSrcRgaBuf = wrapbuffer_virtualaddr(inputBuf, mCfg.src_w, mCfg.src_h, mCfg.src_fmt);
    mDstRgaBuf = wrapbuffer_virtualaddr(outputBuf, mCfg.dst_w, mCfg.dst_h, mCfg.dst_fmt);
    if(mSrcRgaBuf.width == 0 || mDstRgaBuf.width == 0) {
        printf("%s, %s\n", __FUNCTION__, imStrError());
        return -1;
    }

    mSrcRgaBuf.format = mCfg.src_fmt;
    mDstRgaBuf.format = mCfg.dst_fmt;
    
    int ret = imcheck(mSrcRgaBuf, mDstRgaBuf, mSrcRect, mDstRect);
    if (IM_STATUS_NOERROR != ret) {
        printf("%d, check error! %s \n", __LINE__, imStrError((IM_STATUS)ret));
        return -1;
    }

    // struct timeval start, end;
    // gettimeofday(&start, NULL);

    IM_STATUS STATUS = imcvtcolor(mSrcRgaBuf, mDstRgaBuf, mSrcRgaBuf.format, mDstRgaBuf.format);

    // gettimeofday(&end, NULL);
    // long usec1 = 1000000 * (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec);
    // printf("cvtcolor .... cost time %ld us, %s\n", usec1, imStrError(STATUS));
    return 0;

}